import { JSONCodec, NatsConnection } from "nats";
import { mnetMsg } from "../../typeDef";
import { makeForwardSubjectName } from "../forwardUtils";
import { mnetForwardReaderInterface } from "../mnetForwardReaderInterface";

const sc = JSONCodec<mnetMsg>()

export class mnetNatsReader implements mnetForwardReaderInterface {

    constructor(
        conn:NatsConnection,
        defaultErrMsg:mnetMsg

    ) {
        this.mConn = conn
        this.mDefaultErrMsg = defaultErrMsg
    }

    //Subscribe to a notification type message
    subscribeNotify(readerName:string,msgName:string,recvCallback:(msg:mnetMsg)=>void):void {
        const subjectName:string = makeForwardSubjectName(readerName,msgName)
        const subscription = this.mConn.subscribe(subjectName);
        (async () => {
            for await (const msg of subscription) {
                try {
                    const requestData = sc.decode(msg.data)
 
                    try { 
                        recvCallback(requestData)
                    }catch(errMsg) {
                        console.error('Notify message processing failed:', subjectName,errMsg)
                    }                   
                } catch (err) {
                    console.error('Notify message processing failed#1:', subjectName,err)
                }
            }
        })();
    }

    //Subscribe to a request type message
    subscribeRequest(readerName:string,msgName:string,recvCallback:(msg:mnetMsg)=>mnetMsg):void {
        const subjectName:string = makeForwardSubjectName(readerName,msgName)
        const subscription = this.mConn.subscribe(subjectName);
        (async () => {
            for await (const msg of subscription) {
                try {
                    const requestData = sc.decode(msg.data)

                    var reData:mnetMsg|undefined
                    try { 
                        reData = recvCallback(requestData)
                    }catch(errMsg) {
                        console.error('Request message processing failed:', subjectName,errMsg)
                    }

                    msg.respond(sc.encode(reData??this.mDefaultErrMsg))                    
                } catch (err) {
                    console.error('Request message processing failed#1:', subjectName,err)
                }
            }
        })();
    }
    private mDefaultErrMsg:mnetMsg
    private mConn:NatsConnection
}


   